package com.xbongbong.workflow.rabbitmq.consumer;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.xbongbong.coolapp.service.CoolAppCardService;
import com.xbongbong.paas.config.enums.WorkflowExecutionStatusEnum;
import com.xbongbong.paas.config.enums.WorkflowTaskLogStatusEnum;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.PaasProcessDataEntity;
import com.xbongbong.paas.domain.entity.StageWorkflowEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.PlatFormEnum;
import com.xbongbong.paas.enums.StageWorkflowTriggerTypeEnum;
import com.xbongbong.paas.enums.TaskTypeEnum;
import com.xbongbong.paas.exception.WorkflowException;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.help.FlowStatusHelp;
import com.xbongbong.paas.help.FormDataHelp;
import com.xbongbong.paas.help.ProFormHelp;
import com.xbongbong.paas.help.WorkflowHelp;
import com.xbongbong.paas.model.StageWorkflowModel;
import com.xbongbong.paas.pojo.dto.ActiveRuleDTO;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.redis.RedisTimeConstant;
import com.xbongbong.paas.service.ExecuteBusinessRuleService;
import com.xbongbong.pro.service.dingtalk.WorkflowDingtalkService;
import com.xbongbong.paas.service.dingtalkTodo.WorkflowDingtalkTodoService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.thread.TransmittableThreadLocalUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.WorkflowUtil;
import com.xbongbong.parent.interfaces.FormDataUpdateService;
import com.xbongbong.pro.coolapp.pojo.dto.CoolAppWorkflowCardDTO;
import com.xbongbong.pro.enums.PackageTypeEnum;
import com.xbongbong.pro.enums.errorcodes.ProErrorCodeEnum;
import com.xbongbong.pro.enums.workrecord.enums.WorkrecordResultEnum;
import com.xbongbong.pro.formdata.pojo.SaasNeedRedundantAttrPojo;
import com.xbongbong.pro.service.toolbox.data.ProFormDataHelp;
import com.xbongbong.pro.thread.ThreadPoolBeanConfig;
import com.xbongbong.pro.workflow.enums.WorkflowExecutionTypeEnum;
import com.xbongbong.pro.workflow.enums.WorkflowOperateEnum;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.model.IndexTypeModel;
import com.xbongbong.saas.model.PaasFormSubDataModel;
import com.xbongbong.sys.model.UserModel;
import com.xbongbong.workflow.domain.entity.WorkflowBackupDataEntity;
import com.xbongbong.workflow.domain.entity.WorkflowBackupRichTextEntity;
import com.xbongbong.workflow.domain.entity.WorkflowEntity;
import com.xbongbong.workflow.domain.entity.WorkflowExecutionEntity;
import com.xbongbong.workflow.domain.entity.WorkflowNodeEntity;
import com.xbongbong.workflow.domain.entity.WorkflowTaskEntity;
import com.xbongbong.workflow.domain.entity.WorkflowTaskLogEntity;
import com.xbongbong.workflow.domain.entity.WorkflowTransferDataEntity;
import com.xbongbong.workflow.enums.WorkflowNodeTypeEnum;
import com.xbongbong.workflow.model.WorkflowBackupDataModel;
import com.xbongbong.workflow.model.WorkflowBackupRichTextModel;
import com.xbongbong.workflow.model.WorkflowExecutionModel;
import com.xbongbong.workflow.model.WorkflowModel;
import com.xbongbong.workflow.model.WorkflowNodeModel;
import com.xbongbong.workflow.model.WorkflowTaskLogModel;
import com.xbongbong.workflow.model.WorkflowTaskModel;
import com.xbongbong.workflow.model.WorkflowTaskNodeModel;
import com.xbongbong.workflow.model.WorkflowTransferDataModel;
import com.xbongbong.workflow.pojo.Data;
import com.xbongbong.workflow.pojo.WorkflowProcessResultPojo;
import com.xbongbong.workflow.pojo.WorkflowRabbitmqDTO;
import com.xbongbong.workflow.pojo.WorkflowTransferPOJO;
import com.xbongbong.workflow.producer.WorkflowProducer;
import com.xbongbong.workflow.rabbitmq.binders.WorkflowMqConsumerBinder;
import com.xbongbong.workflow.rabbitmq.constant.WorkflowMqConsumerConstant;
import com.xbongbong.workflow.service.help.WorkflowDataHelp;
import com.xbongbong.workflow.service.strategy.node.WorkflowNodeStrategy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.annotation.StreamListener;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * workflow 消费者
 * @author 魏荣杰
 *
 */
@EnableBinding(WorkflowMqConsumerBinder.class)
public class WorkflowListener {
    private static final Logger LOGGER = LoggerFactory.getLogger(WorkflowListener.class);

    @Resource
    private WorkflowNodeModel workflowNodeModel;
    @Resource
    private Map<String, WorkflowNodeStrategy> workflowNodeStrategyMap;
    @Resource
    private WorkflowHelp workflowHelp;
    @Resource
    private WorkflowTransferDataModel workflowTransferDataModel;
    @Resource
    private WorkflowTaskLogModel workflowTaskLogModel;
    @Resource
    private WorkflowTaskModel workflowTaskModel;
    @Resource
    private WorkflowDataHelp workflowDataHelp;
    @Resource
    private WorkflowModel workflowModel;
    @Resource
    private WorkflowBackupDataModel workflowBackupDataModel;
    @Resource
    private ProFormDataHelp proFormDataHelp;
    @Resource
    private FormDataHelp formDataHelp;
    @Resource
    private WorkflowTaskNodeModel workflowTaskNodeModel;
    @Resource
    private ExecuteBusinessRuleService executeBusinessRuleService;
    @Resource
    private UserModel userModel;
    @Resource
    private PaasFormSubDataModel paasFormSubDataModel;
    @Resource
    private ProFormHelp proFormHelp;
    @Resource
    private WorkflowDingtalkTodoService workflowDingtalkTodoService;
    @Resource
    private WorkflowDingtalkService workflowDingtalkService;
    @Resource
    private IndexTypeModel indexTypeModel;
    @Resource
    private WorkflowExecutionModel workflowExecutionModel;
    @Resource
    private StageWorkflowModel stageWorkflowModel;
    @Resource
    private WorkflowProducer workflowProducer;
    @Resource
    private PaasRedisHelper paasRedisHelper;
    @Resource
    private CommonHelp commonHelp;
    @Resource
    private CoolAppCardService coolAppCardService;
    @Resource
    private ThreadPoolBeanConfig threadPoolBeanConfig;
    @Resource
    private WorkflowBackupRichTextModel workflowBackupRichTextModel;
    @Resource
    private FlowStatusHelp flowStatusHelp;
    @Resource
    private Map<Integer, FormDataUpdateService> businessUpdateMap;


    @StreamListener(value = WorkflowMqConsumerConstant.WORKFLOW_START_INPUT)
    public void workflowReceive(WorkflowRabbitmqDTO workflowRabbitmqDTO) {
        WorkflowTransferPOJO workflowTransferPOJO = workflowRabbitmqDTO.getWorkflowTransferPOJO();
        try {
            LOGGER.warn("workflow Receive ------ xbbreftype = " + XbbRefTypeEnum.getByCode(workflowTransferPOJO.getData().getBusinessType()) + "\n ---data=  " + JSON.toJSONString(workflowTransferPOJO.getData()));
            if (workflowRabbitmqDTO.getWorkflowTransferPOJO().getIsFromStage() && Objects.isNull(workflowRabbitmqDTO.getWorkflowTransferPOJO().getLinkKey())) {
                // 生成linkKey
                workflowRabbitmqDTO.getWorkflowTransferPOJO().setLinkKey(UUID.randomUUID().toString().replaceAll("-", ""));
            }
            WorkflowNodeEntity startNode = workflowRabbitmqDTO.getWorkflowNodeEntity();
            SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo = workflowRabbitmqDTO.getSaasNeedRedundantAttrPojo();
            LOGGER.warn("workflow Receive -------------- " + startNode.getName());
            boolean isApproval = extracted(startNode, workflowTransferPOJO, saasNeedRedundantAttrPojo);
            // 执行完工作流后删除中间流转数据
//            if (Objects.nonNull(workflowTransferPOJO.getTaskId())) {
//                workflowTransferDataModel.deleteByTaskId(workflowTransferPOJO.getTaskId(), workflowTransferPOJO.getCorpid());
//            }
            // 备份逻辑
            backup(workflowTransferPOJO, startNode, saasNeedRedundantAttrPojo);
            // 工作流后续新建编辑操作
            endWorkflow(workflowTransferPOJO, saasNeedRedundantAttrPojo, isApproval);

            // 是否为新建，startNode--uid==startNode
            if (isApproval) {
                if (Objects.equals(startNode.getUid(), WorkflowNodeTypeEnum.START_NODE.getName())) {
                    // 添加卡片
                    if (Objects.nonNull(workflowRabbitmqDTO.getOpenConversationId())) {
                        coolAppCard(workflowRabbitmqDTO, false, FlowStatusEnum.IN_APPROVAL.getType(), TaskTypeEnum.COMMIT.getType());
                    } else {
                        // 没有群id默认走更新卡片接口
                        coolAppCard(workflowRabbitmqDTO, true, FlowStatusEnum.APPROVAL_PENDING.getType(), TaskTypeEnum.AGAIN_COMMIT.getType());
                    }
                } else {
                    // 退回
                    coolAppCard(workflowRabbitmqDTO, true, FlowStatusEnum.REFUSE.getType(), TaskTypeEnum.BACK.getType());
                }
            }

        } catch (WorkflowException e) {
            LOGGER.error(e.getMsg(), e);
            if (Objects.nonNull(workflowTransferPOJO.getTaskId())) {
                workflowTransferDataModel.deleteByTaskId(workflowTransferPOJO.getTaskId(), workflowTransferPOJO.getCorpid());
            }
            // 工作流执行器处理
            updateWorkflowExecution(workflowTransferPOJO, WorkflowExecutionStatusEnum.FAIL);

        } catch (Exception e) {
            LOGGER.error("com.xbongbong.workflow.rabbitmq.consumer.WorkflowListener.workflowReceive", e);
            if (Objects.nonNull(workflowTransferPOJO.getTaskId())) {
                workflowTransferDataModel.deleteByTaskId(workflowTransferPOJO.getTaskId(), workflowTransferPOJO.getCorpid());
            }
            // 工作流执行器处理
            updateWorkflowExecution(workflowTransferPOJO, WorkflowExecutionStatusEnum.FAIL);
        }

    }

    /* *
     * Description: 更新工作流执行器状态
     * @param workflowTransferPOJO
	 * @param workflowExecutionStatusEnum
     * @author 魏荣杰
     */
    private void updateWorkflowExecution(WorkflowTransferPOJO workflowTransferPOJO, WorkflowExecutionStatusEnum workflowExecutionStatusEnum) {
        if (!Objects.isNull(workflowTransferPOJO.getExecutionId()) && !Objects.equals(workflowTransferPOJO.getExecutionId(), 0L)) {
            WorkflowExecutionEntity workflowExecutionEntity = new WorkflowExecutionEntity();
            workflowExecutionEntity.setId(workflowTransferPOJO.getExecutionId());
            workflowExecutionEntity.setCorpid(workflowTransferPOJO.getCorpid());
            workflowExecutionEntity.setTaskId(workflowTransferPOJO.getTaskId());
            workflowExecutionEntity.setStatus(workflowExecutionStatusEnum.getCode());
            workflowExecutionModel.update(workflowExecutionEntity);
        }
    }

    @StreamListener(value = WorkflowMqConsumerConstant.WORKFLOW_OPERATOR_INPUT)
    public void workflowOperatorReceive(WorkflowRabbitmqDTO workflowRabbitmqDTO) {
        WorkflowTransferPOJO workflowTransferPOJO = workflowRabbitmqDTO.getWorkflowTransferPOJO();
        try {
            WorkflowNodeEntity workflowNodeEntity = workflowRabbitmqDTO.getWorkflowNodeEntity();
            SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo = workflowRabbitmqDTO.getSaasNeedRedundantAttrPojo();
            WorkflowNodeEntity startNode = workflowHelp.deliverToNextNode(workflowTransferPOJO, workflowNodeEntity);

            // 下一个节点没有直接结束
            if (Objects.isNull(startNode)) {

                // 执行完工作流后删除中间流转数据
                if (Objects.nonNull(workflowTransferPOJO.getTaskId())) {
                    //todo 如果有审批，没有下一个节点的时候需要把 状态 置成通过
                    if (!Objects.equals(workflowTransferPOJO.getRefuseFlag(), true)) {
                        workflowTaskModel.updateFlowStatusByTaskId(workflowNodeEntity.getCorpid(), workflowTransferPOJO.getTaskId(), FlowStatusEnum.PASS.getType());
                    }
                    workflowTransferDataModel.deleteByTaskId(workflowTransferPOJO.getTaskId(), workflowTransferPOJO.getCorpid());
                }
                endWorkflow(workflowTransferPOJO, saasNeedRedundantAttrPojo, false);

                // 更新日志，标志工作流完成
                WorkflowTaskLogEntity workflowTaskLogEntity = new WorkflowTaskLogEntity();
                workflowTaskLogEntity.setId(workflowTransferPOJO.getLogId());
                workflowTaskLogEntity.setCorpid(workflowTransferPOJO.getCorpid());
                workflowTaskLogEntity.setStatus(WorkflowTaskLogStatusEnum.PASS.getType());
                workflowTaskLogEntity.setExitTime(DateTimeUtil.getInt());
                workflowTaskLogEntity.setUpdateTime(DateTimeUtil.getInt());
                workflowTaskLogModel.update(workflowTaskLogEntity);

                // 同意
                coolAppCard(workflowRabbitmqDTO, true, FlowStatusEnum.PASS.getType(), TaskTypeEnum.COMMIT.getType());
                return;
            }

            boolean isApproval = extracted(startNode, workflowTransferPOJO, saasNeedRedundantAttrPojo);
            // 执行完工作流后删除中间流转数据
//            if (Objects.nonNull(workflowTransferPOJO.getTaskId())) {
//                workflowTransferDataModel.deleteByTaskId(workflowTransferPOJO.getTaskId(), workflowTransferPOJO.getCorpid());
//            }

            // 工作流后续新建编辑操作
            endWorkflow(workflowTransferPOJO, saasNeedRedundantAttrPojo, isApproval);

            // 是否结束
            Integer flowStatus = isApproval ? FlowStatusEnum.IN_APPROVAL.getType() : FlowStatusEnum.PASS.getType();
            coolAppCard(workflowRabbitmqDTO, true, flowStatus, TaskTypeEnum.COMMIT.getType());
        } catch (WorkflowException e) {
            LOGGER.error(e.getMsg(), e);
            if (Objects.nonNull(workflowTransferPOJO.getTaskId())) {
                workflowTransferDataModel.deleteByTaskId(workflowTransferPOJO.getTaskId(), workflowTransferPOJO.getCorpid());
            }
        } catch (Exception e) {
            LOGGER.error("com.xbongbong.workflow.rabbitmq.consumer.WorkflowListener#workflowOperatorReceive", e);
            if (Objects.nonNull(workflowTransferPOJO.getTaskId())) {
                workflowTransferDataModel.deleteByTaskId(workflowTransferPOJO.getTaskId(), workflowTransferPOJO.getCorpid());
            }
        }
    }

    @StreamListener(value = WorkflowMqConsumerConstant.WORKFLOW_OPERATOR_NO_APPROVE_INPUT)
    public void workflowOperatorNoApproveReceive(WorkflowRabbitmqDTO workflowRabbitmqDTO) {
        WorkflowTransferPOJO workflowTransferPojo = workflowRabbitmqDTO.getWorkflowTransferPOJO();
        try {
            WorkflowNodeEntity workflowNodeEntity = workflowRabbitmqDTO.getWorkflowNodeEntity();
            WorkflowNodeEntity startNode = workflowRabbitmqDTO.getWorkflowNodeEntity();

            // 下一个节点没有直接结束
            if (Objects.isNull(startNode)) {
                return;
            }
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put(StringConstant.CORPID, workflowNodeEntity.getCorpid());
            param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
            param.put("workflowId", workflowNodeEntity.getWorkflowId());
            param.put("typeIn", WorkflowNodeTypeEnum.getDataProcessingNodeList());
            Integer count = workflowNodeModel.getEntitysCount(param);
            if (count == 0) {
                // 如果该工作流都是审批相关，无数据处理的节点，则无需执行，避免下方死循环
                return;
            }
            extractedNoApprove(startNode, workflowTransferPojo);

            endWorkflow(workflowTransferPojo, workflowRabbitmqDTO.getSaasNeedRedundantAttrPojo(), false);

        }
//        catch (WorkflowException e) {
//            LOGGER.error(e.getMsg(), e);
//            if (Objects.nonNull(workflowTransferPOJO.getTaskId())) {
//                workflowTransferDataModel.deleteByTaskId(workflowTransferPOJO.getTaskId(), workflowTransferPOJO.getCorpid());
//            }
//        }
        catch (Exception e) {
            LOGGER.error("WorkflowListener#workflowOperatorNoApproveReceive", e);
        }
    }

    private boolean extracted(WorkflowNodeEntity startNode, WorkflowTransferPOJO workflowTransferPOJO, SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo) throws XbbException {
        Integer type = startNode.getType();
        WorkflowNodeEntity nowNode = startNode;

        Long lastNodeId = 0L;
        // 初始节点判断，如果不是拿之前节点的id
        if (!Objects.equals(nowNode.getPrevId(), "0")) {
            WorkflowNodeEntity lastNode = workflowNodeModel.getByUId(nowNode.getWorkflowId(), nowNode.getCorpid(), nowNode.getPrevId());
            lastNodeId = lastNode.getId();
        }
        // 是否进审批
        boolean isApproval = false;
        while (true) {

            // 如果是审批拒绝过来的要过滤后面的所有审批节点，不执行，并且后续逻辑只执行到拒绝分支所在条件块
            if (Objects.equals(workflowTransferPOJO.getRefuseFlag(), true)) {

                // 拒绝后
                if (!Objects.equals(WorkflowNodeTypeEnum.CONDITION_BLOCK_NODE.getType(), startNode.getType())) {
                    break;
                }

                if (Objects.equals(startNode.getUid(), nowNode.getPrevId()) && !Objects.equals(nowNode.getWrapperId(), startNode.getUid())) {
                    // 走拒绝的逻辑只执行到当前条件块内的所有节点
                    break;
                }

                if (Objects.equals(WorkflowNodeTypeEnum.APPROVE_NODE.getType(), nowNode.getType())) {
                    WorkflowNodeEntity nextNode = workflowHelp.deliverToNextNode(workflowTransferPOJO, nowNode);

                    if (Objects.isNull(nextNode)) {
                        // 没有节点了，结束, 或者拒绝的条件块结束
                        // 更新日志，标志工作流完成
                        WorkflowTaskLogEntity workflowTaskLogEntity = new WorkflowTaskLogEntity();
                        workflowTaskLogEntity.setCorpid(workflowTransferPOJO.getCorpid());
                        workflowTaskLogEntity.setId(workflowTransferPOJO.getLogId());
                        workflowTaskLogEntity.setStatus(WorkflowTaskLogStatusEnum.PASS.getType());
                        workflowTaskLogEntity.setExitTime(DateTimeUtil.getInt());
                        workflowTaskLogEntity.setUpdateTime(DateTimeUtil.getInt());
                        workflowTaskLogModel.update(workflowTaskLogEntity);
                        break;
                    }

                    lastNodeId = nowNode.getId();
                    type = nextNode.getType();
                    nowNode = nextNode;
                    continue;
                }
            }

            String nodeTypeNameByType = WorkflowNodeTypeEnum.getNodeTypeNameByType(type);
            WorkflowNodeStrategy workflowNodeStrategy = workflowNodeStrategyMap.get(nodeTypeNameByType);
            workflowNodeStrategy.before(workflowTransferPOJO);
            WorkflowProcessResultPojo workflowProcessResultPojo = workflowNodeStrategy.process(workflowTransferPOJO, nowNode, lastNodeId, saasNeedRedundantAttrPojo);
            boolean result = workflowProcessResultPojo.getResult();
            Boolean isAutoApproval = workflowProcessResultPojo.getIsAutoApproval();
            Boolean isSuspend = workflowProcessResultPojo.getIsSuspend();
            workflowNodeStrategy.after(workflowTransferPOJO, nowNode);
            if (Objects.equals(nowNode.getType(), WorkflowNodeTypeEnum.APPROVE_NODE.getType()) && result) {
                // 进到审批并且需要审批也停止，等审批后触发
                // 存储中间流转上下文
                if (Objects.nonNull(workflowTransferPOJO.getTaskId()) && !Objects.equals(workflowTransferPOJO.getTaskId(), 0L)) {
                    WorkflowTransferDataEntity workflowTransferDataEntity = workflowTransferDataModel.getByTaskId(workflowTransferPOJO.getTaskId(), workflowTransferPOJO.getCorpid());
                    if (Objects.isNull(workflowTransferDataEntity)) {
                        WorkflowTransferDataEntity dataEntity = new WorkflowTransferDataEntity();
                        dataEntity.setData(JSON.parseObject(JSON.toJSONString(workflowTransferPOJO, SerializerFeature.DisableCircularReferenceDetect)));
                        if (Objects.nonNull(saasNeedRedundantAttrPojo)) {
                            dataEntity.setSaasNeedPojo(JSON.parseObject(JSON.toJSONString(saasNeedRedundantAttrPojo, SerializerFeature.DisableCircularReferenceDetect)));
                        }
                        dataEntity.setWorkflowId(nowNode.getWorkflowId());
                        dataEntity.setCorpid(workflowTransferPOJO.getCorpid());
                        dataEntity.setTaskId(workflowTransferPOJO.getTaskId());
                        dataEntity.setLogId(workflowTransferPOJO.getLogId());
                        dataEntity.setFormId(startNode.getFormId());
                        dataEntity.setSaasMark(startNode.getSaasMark());
                        dataEntity.setBusinessType(startNode.getBusinessType());
                        dataEntity.setOperate(workflowTransferPOJO.getOperate());
                        dataEntity.setDataId(workflowTransferPOJO.getData().getId());
                        dataEntity.setDel(DelEnum.NORMAL.getDel());
                        workflowTransferDataModel.insert(dataEntity);
                    } else {
                        workflowTransferDataEntity.setData(JSON.parseObject(JSON.toJSONString(workflowTransferPOJO, SerializerFeature.DisableCircularReferenceDetect)));
                        if (Objects.nonNull(saasNeedRedundantAttrPojo)) {
                            workflowTransferDataEntity.setSaasNeedPojo(JSON.parseObject(JSON.toJSONString(saasNeedRedundantAttrPojo, SerializerFeature.DisableCircularReferenceDetect)));
                        }
                        workflowTransferDataModel.update(workflowTransferDataEntity);
                    }
                }
                // 不是自动通过的审批节点都是需要人工操作，都要进审批处理，终止工作流流转
                if (!isAutoApproval) {
                    isApproval = true;
                    break;
                }
            }
            WorkflowNodeEntity nextNode = workflowHelp.deliverToNextNode(workflowTransferPOJO, nowNode);
            if (!result && !Objects.equals(WorkflowNodeTypeEnum.APPROVE_NODE.getType(), nowNode.getType())) {
                // 执行失败，结束
                // 结束删除上下文
                if (Objects.nonNull(workflowTransferPOJO.getTaskId())) {
                    // 其他节点执行失败，如果有审批，标识审批通过
                    if (!Objects.equals(workflowTransferPOJO.getRefuseFlag(), true)) {
                        workflowTaskModel.updateFlowStatusByTaskId(workflowTransferPOJO.getCorpid(), workflowTransferPOJO.getTaskId(), FlowStatusEnum.PASS.getType());
                    }
                    // 结束删除上下文
                    workflowTransferDataModel.deleteByTaskId(workflowTransferPOJO.getTaskId(), workflowTransferPOJO.getCorpid());
                }
                // 更新日志，标志工作流失败
                WorkflowTaskLogEntity workflowTaskLogEntity = new WorkflowTaskLogEntity();
                workflowTaskLogEntity.setId(workflowTransferPOJO.getLogId());
                workflowTaskLogEntity.setCorpid(workflowTransferPOJO.getCorpid());
                if (!Objects.equals(isSuspend, true)) {
                    workflowTaskLogEntity.setStatus(WorkflowTaskLogStatusEnum.FAIL.getType());
                }
                workflowTaskLogEntity.setExitTime(DateTimeUtil.getInt());
                workflowTaskLogEntity.setUpdateTime(DateTimeUtil.getInt());
                workflowTaskLogModel.update(workflowTaskLogEntity);

                // 更新执行器，标志工作流失败
                updateWorkflowExecution(workflowTransferPOJO, WorkflowExecutionStatusEnum.FAIL);

                break;
            } else if (Objects.isNull(nextNode)) {
                // 没有节点了，结束
                if (Objects.nonNull(workflowTransferPOJO.getTaskId())) {
                    // 如果有审批，标识审批通过，更新data的审批状态
                    if (!Objects.equals(workflowTransferPOJO.getRefuseFlag(), true)) {
                        workflowTaskModel.updateFlowStatusByTaskId(workflowTransferPOJO.getCorpid(), workflowTransferPOJO.getTaskId(), FlowStatusEnum.PASS.getType());
                    }
                    // 结束删除上下文
                    workflowTransferDataModel.deleteByTaskId(workflowTransferPOJO.getTaskId(), workflowTransferPOJO.getCorpid());
                }
                // 更新日志，标志工作流完成
                WorkflowTaskLogEntity workflowTaskLogEntity = new WorkflowTaskLogEntity();
                workflowTaskLogEntity.setId(workflowTransferPOJO.getLogId());
                workflowTaskLogEntity.setCorpid(workflowTransferPOJO.getCorpid());
                workflowTaskLogEntity.setStatus(WorkflowTaskLogStatusEnum.PASS.getType());
                workflowTaskLogEntity.setExitTime(DateTimeUtil.getInt());
                workflowTaskLogEntity.setUpdateTime(DateTimeUtil.getInt());
                workflowTaskLogModel.update(workflowTaskLogEntity);
                break;
            }
            lastNodeId = nowNode.getId();
            type = nextNode.getType();
            nowNode = nextNode;
        }
        return isApproval;
    }

    /**
     * 无审批节点，无抄送节点，无消息节点
     * @param startNode
     * @param workflowTransferPOJO
     * @throws XbbException
     */
    private void extractedNoApprove(WorkflowNodeEntity startNode, WorkflowTransferPOJO workflowTransferPOJO) throws XbbException {
        Integer type = startNode.getType();
        WorkflowNodeEntity nowNode = startNode;

        Long lastNodeId = 0L;
        // 初始节点判断，如果不是拿之前节点的id
        if (!Objects.equals(nowNode.getPrevId(), "0")) {
            WorkflowNodeEntity lastNode = workflowNodeModel.getByUId(nowNode.getWorkflowId(), nowNode.getCorpid(), nowNode.getPrevId());
            lastNodeId = lastNode.getId();
        }
        Integer operator = workflowTransferPOJO.getOperate();
        while (true) {
            // 批量编辑和批量删除，导入，导入覆盖，跳过审批节点，抄送节点，消息节点，直接获取下一个节点
            boolean batch = Arrays.asList(WorkflowOperateEnum.UPDATE_BATCH.getType(), WorkflowOperateEnum.DELETE_BATCH.getType(), WorkflowOperateEnum.ADD.getType(), WorkflowOperateEnum.UPDATE.getType()).contains(operator)
                    && !Objects.equals(nowNode.getType(), WorkflowNodeTypeEnum.START_NODE.getType())
                    && !Objects.equals(nowNode.getType(), WorkflowNodeTypeEnum.CONDITION_NODE.getType())
                    && !Objects.equals(nowNode.getType(), WorkflowNodeTypeEnum.CONDITION_BLOCK_NODE.getType())
                    && !WorkflowNodeTypeEnum.getDataProcessingNodeList().contains(nowNode.getType());
            // 详情页的删除，跳过审批节点，抄送节点，直接获取下一个节点
            boolean singleDelete = Objects.equals(operator, WorkflowOperateEnum.DELETE.getType() )
                    && !Objects.equals(nowNode.getType(), WorkflowNodeTypeEnum.START_NODE.getType())
                    && !Objects.equals(nowNode.getType(), WorkflowNodeTypeEnum.CONDITION_NODE.getType())
                    && !Objects.equals(nowNode.getType(), WorkflowNodeTypeEnum.CONDITION_BLOCK_NODE.getType())
                    && !Objects.equals(nowNode.getType(), WorkflowNodeTypeEnum.SEND_MESSAGE_NODE.getType())
                    && !WorkflowNodeTypeEnum.getDataProcessingNodeList().contains(nowNode.getType());
            if (batch || singleDelete) {
                // 跳过审批节点，抄送节点，消息节点，直接获取下一个节点
                WorkflowNodeEntity nextNode = workflowHelp.deliverToNextNode(workflowTransferPOJO, nowNode);
                lastNodeId = nowNode.getId();
                if (Objects.isNull(nextNode)) {
                    // 没有节点了，结束
                    // 更新日志，标志工作流完成
                    WorkflowTaskLogEntity workflowTaskLogEntity = new WorkflowTaskLogEntity();
                    workflowTaskLogEntity.setCorpid(workflowTransferPOJO.getCorpid());
                    workflowTaskLogEntity.setId(workflowTransferPOJO.getLogId());
                    workflowTaskLogEntity.setStatus(WorkflowTaskLogStatusEnum.PASS.getType());
                    workflowTaskLogEntity.setExitTime(DateTimeUtil.getInt());
                    workflowTaskLogEntity.setUpdateTime(DateTimeUtil.getInt());
                    workflowTaskLogModel.update(workflowTaskLogEntity);
                    break;
                }
                type = nextNode.getType();
                nowNode = nextNode;
                continue;
            }
            String nodeTypeNameByType = WorkflowNodeTypeEnum.getNodeTypeNameByType(type);
            WorkflowNodeStrategy workflowNodeStrategy = workflowNodeStrategyMap.get(nodeTypeNameByType);
            workflowNodeStrategy.before(workflowTransferPOJO);
            WorkflowProcessResultPojo workflowProcessResultPojo = workflowNodeStrategy.process(workflowTransferPOJO, nowNode, lastNodeId, null);
            Boolean result = workflowProcessResultPojo.getResult();
            Boolean isSuspend = workflowProcessResultPojo.getIsSuspend();
            workflowNodeStrategy.after(workflowTransferPOJO, nowNode);
            WorkflowNodeEntity nextNode = workflowHelp.deliverToNextNode(workflowTransferPOJO, nowNode);
            if (!result && !Objects.equals(WorkflowNodeTypeEnum.APPROVE_NODE.getType(), nowNode.getType())) {
                // 执行失败，结束
                // 结束删除上下文
                // 更新日志，标志工作流失败
                WorkflowTaskLogEntity workflowTaskLogEntity = new WorkflowTaskLogEntity();
                workflowTaskLogEntity.setId(workflowTransferPOJO.getLogId());
                workflowTaskLogEntity.setCorpid(workflowTransferPOJO.getCorpid());
                if (!Objects.equals(isSuspend, true)) {
                    workflowTaskLogEntity.setStatus(WorkflowTaskLogStatusEnum.FAIL.getType());
                }
                workflowTaskLogEntity.setExitTime(DateTimeUtil.getInt());
                workflowTaskLogEntity.setUpdateTime(DateTimeUtil.getInt());
                workflowTaskLogModel.update(workflowTaskLogEntity);
                break;
            } else if (Objects.isNull(nextNode)) {
                // 没有节点了，结束
                // 更新日志，标志工作流完成
                WorkflowTaskLogEntity workflowTaskLogEntity = new WorkflowTaskLogEntity();
                workflowTaskLogEntity.setId(workflowTransferPOJO.getLogId());
                workflowTaskLogEntity.setCorpid(workflowTransferPOJO.getCorpid());
                workflowTaskLogEntity.setStatus(WorkflowTaskLogStatusEnum.PASS.getType());
                workflowTaskLogEntity.setExitTime(DateTimeUtil.getInt());
                workflowTaskLogEntity.setUpdateTime(DateTimeUtil.getInt());
                workflowTaskLogModel.update(workflowTaskLogEntity);
                break;
            }
            lastNodeId = nowNode.getId();
            type = nextNode.getType();
            nowNode = nextNode;
        }
    }
    /**
     * Description: 工作流结束后的数据特殊操作
     * @param workflowTransferPOJO
	 * @param saasNeedRedundantAttrPojo
     * @param isApproval
     * @return void
     * @throws
     * @author 魏荣杰
     * @date 2021/7/12 13:51
     * @since
     */
    public void endWorkflow(WorkflowTransferPOJO workflowTransferPOJO, SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo, boolean isApproval) throws XbbException {
        if (!isApproval && !Objects.equals(workflowTransferPOJO.getRefuseFlag(), true)) {
            String corpid = workflowTransferPOJO.getCorpid();
            Integer saasMark = workflowTransferPOJO.getData().getSaasMark();
            Integer businessType = workflowTransferPOJO.getData().getBusinessType();
            PaasFormDataEntity paasFormDataEntityExt = WorkflowUtil.setData(workflowTransferPOJO.getData().getId(), corpid, workflowTransferPOJO.getData());
            Long formId = workflowTransferPOJO.getData().getFormId();
            Long dataId = workflowTransferPOJO.getData().getId();
            if (Objects.equals(workflowTransferPOJO.getOperate(), WorkflowOperateEnum.ADD.getType())) {

                setWorkFlowOperateValue(businessType, workflowTransferPOJO.getOperate());
                // 新建
                workflowDataHelp.processForSave(workflowTransferPOJO, saasNeedRedundantAttrPojo);
                // 业务规则触发
                PaasFormEntity paasFormEntity = proFormHelp.getPaasForm(formId, businessType, corpid);
                String businessRules = paasFormEntity.getBusinessRules();
                if ( Objects.equals("1", businessRules)) {
                    UserVO userVO = userModel.getUserVO(corpid, workflowTransferPOJO.getUser().getUserId(), true, true);
                    IndexTypeEnum indexTypeEnum = indexTypeModel.getSubIndexType(corpid, businessType, saasMark);
                    paasFormSubDataModel.transferSubForm(paasFormDataEntityExt, indexTypeEnum);
                    try {
                        ActiveRuleDTO activeRuleDTO = new ActiveRuleDTO(paasFormDataEntityExt, new ArrayList<>(), paasFormDataEntityExt.getId(), paasFormEntity.getId(), businessType, saasMark,
                                corpid, userVO, 0, PlatFormEnum.INTERNAL.getValue());

                        executeBusinessRuleService.execute(activeRuleDTO);
                    }catch (Exception e){
                        LOGGER.error("触发工作流后触发业务规则", e);
                    }
                }

            } else if (Objects.equals(workflowTransferPOJO.getOperate(), WorkflowOperateEnum.UPDATE.getType())) {
                // 编辑
                workflowDataHelp.processForUpdate(workflowTransferPOJO, saasNeedRedundantAttrPojo);
                // 业务规则触发
                PaasFormEntity paasFormEntity = proFormHelp.getPaasForm(paasFormDataEntityExt.getFormId(), businessType, corpid);
                String businessRules = paasFormEntity.getBusinessRules();
                if ( Objects.equals("1", businessRules)) {
                    PaasFormDataEntityExt oldFormData = WorkflowUtil.setData(workflowTransferPOJO.getOldData().getId(), corpid, workflowTransferPOJO.getOldData());
                    UserVO userVO = userModel.getUserVO(corpid, workflowTransferPOJO.getUser().getUserId(), true, true);
                    IndexTypeEnum indexTypeEnum = indexTypeModel.getSubIndexType(corpid, businessType, saasMark);
                    paasFormSubDataModel.transferSubForm(paasFormDataEntityExt, indexTypeEnum);
                    paasFormSubDataModel.transferSubForm(oldFormData, indexTypeEnum);
                    try{
                        ActiveRuleDTO activeRuleDTO = new ActiveRuleDTO(paasFormDataEntityExt, oldFormData, new ArrayList<>(),  paasFormDataEntityExt.getId(), paasFormEntity.getId(), businessType, saasMark, corpid, userVO, 1, PlatFormEnum.INTERNAL.getValue());

                        executeBusinessRuleService.execute(activeRuleDTO);
                    }catch (Exception e){
                        LOGGER.error("触发工作流后触发业务规则", e);
                    }
                }

            } else if (Objects.equals(workflowTransferPOJO.getOperate(), WorkflowOperateEnum.DELETE.getType())) {
                // 删除

            }
            // 更新主表状态为审批通过
            Data pojoData = workflowTransferPOJO.getData();
            PaasProcessDataEntity paasProcessDataEntity = new PaasProcessDataEntity();
            paasProcessDataEntity.setCorpid(corpid);
            paasProcessDataEntity.setSaasMark(pojoData.getSaasMark());
            paasProcessDataEntity.setFormDataId(pojoData.getId());
            paasProcessDataEntity.setBusinessType(pojoData.getBusinessType());
            // fix：40989 【工作流设计】删除数据节点选择触发表单时，未生效
//            if (Objects.nonNull(paasFormDataEntityExt)) {
//                paasProcessDataEntity.setDel(paasFormDataEntityExt.getDel());
//            }
            WorkflowNodeEntity workflowNodeEntity = workflowNodeModel.getByKey(pojoData.getNodeId(), corpid);
            if (Objects.nonNull(workflowNodeEntity)) {
                WorkflowEntity workflowEntity = workflowModel.getByKey(workflowNodeEntity.getWorkflowId(), corpid);
                Integer count = 0;
                if (Objects.nonNull(workflowTransferPOJO.getTaskId())) {
                    Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    param.put(StringConstant.CORPID, corpid);
                    param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                    param.put("workflowId", workflowEntity.getId());
                    param.put("taskId", workflowTransferPOJO.getTaskId());
                    param.put("nodeType", WorkflowNodeTypeEnum.APPROVE_NODE.getType());
                    param.put("taskType", TaskTypeEnum.COMMIT.getType());
                    count = workflowTaskNodeModel.getEntityCount(param);
                }
                if (Objects.equals(workflowEntity.getIsApprove(), 1) && count > 0) {
                    // 当前执行的工作流，存在审批节点
                    flowStatusHelp.updateFormDataStatus(paasProcessDataEntity, FlowStatusEnum.PASS.getType());

                    // 更新整个钉钉oa审批状态
                    WorkflowTaskEntity workflowTaskEntity = workflowTaskModel.getByKey(workflowTransferPOJO.getTaskId(), corpid);
                    String dingtalkProcessInstanceId = workflowTaskEntity.getDingtalkProcessInstanceId();
                    if (!Objects.isNull(dingtalkProcessInstanceId)) {
                        workflowDingtalkService.updateDingtalkInstance(corpid, dingtalkProcessInstanceId, WorkrecordResultEnum.AGREE);
                    }

                } else {
                    // 当前执行的工作流，没有审批节点
                    flowStatusHelp.updateFormDataStatus(paasProcessDataEntity, FlowStatusEnum.NOT_NEED_APPROVAL.getType());
                }
            } else {
                // 避免节点找不到出现问题，加一行这个代码
                flowStatusHelp.updateFormDataStatus(paasProcessDataEntity, FlowStatusEnum.PASS.getType());
            }

            // 只支持旗舰版
            Integer feeType = commonHelp.getCurrentCompanyPackage(corpid);
            if (Objects.equals(feeType, PackageTypeEnum.ULTIMATE.getType())) {
                // 阶段推进器以及工作流触发工作流处理
                workflowLinkProcess(workflowTransferPOJO, corpid, pojoData);
                // 处理执行器的更新，以及触发下一个要触发的工作流
                updateWorkflowExecution(workflowTransferPOJO, WorkflowExecutionStatusEnum.FINISH);
            }


        }
    }





    /**
     * Description: 阶段推进器以及工作流触发工作流处理
     * @param workflowTransferPOJO
	 * @param corpid
	 * @param pojoData
     * @return void
     * @throws
     * @author 魏荣杰
     * @date 2022/2/17 11:07
     * @since
     */
    private void workflowLinkProcess(WorkflowTransferPOJO workflowTransferPOJO, String corpid, Data pojoData) throws XbbException {
        if (Objects.equals(workflowTransferPOJO.getExecutionType(), WorkflowExecutionTypeEnum.FORM.getCode())) {
            // 表单触发工作流，需要触发后续的工作流触发工作流，以及如果是从阶段推进器触发的需要触发阶段跳出后的工作流,还有工作流触发工作流
            if (workflowTransferPOJO.getIsFromStage()) {
                // 阶段推进器
                // 先处理阶段推进后的，如果没有则触发阶段到达前的
                Long fromStageId = workflowTransferPOJO.getFromStageId();
                if (Objects.isNull(fromStageId)) {
                    return;
                }
                Map<String, Object> param = new HashMap<>();
                param.put(ParameterConstant.CORPID, corpid);
                param.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
                param.put(ParameterConstant.FORMID, pojoData.getFormId());
                param.put("relatedStageId", workflowTransferPOJO.getToStageId());
                param.put("stageId", fromStageId);
                param.put("triggerType", StageWorkflowTriggerTypeEnum.AFTER_STAGE.getCode());
                param.put("stageProcessId", workflowTransferPOJO.getStageProcessId());

                List<StageWorkflowEntity> stageWorkflowEntityList = stageWorkflowModel.findEntitys(param);

                if (CollectionsUtil.isNotEmpty(stageWorkflowEntityList)) {

                    // 根据阶段内的自定义工作流设置去生成相应的工作流
                    List<Long> workflowIds = stageWorkflowEntityList.stream().map(StageWorkflowEntity::getWorkflowId).collect(Collectors.toList());

                    Map<String, Object> params = new HashMap<>();
                    params.put(ParameterConstant.CORPID, corpid);
                    params.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
                    params.put(ParameterConstant.ID_IN, workflowIds);
                    params.put(ParameterConstant.ENABLE, BasicConstant.ONE);
                    List<WorkflowEntity> workflowEntities = workflowModel.findEntitys(params);

                    workflowIds = workflowEntities.stream().map(WorkflowEntity::getId).collect(Collectors.toList());
                    params.clear();
                    params.put(ParameterConstant.CORPID, corpid);
                    params.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
                    params.put("type", WorkflowNodeTypeEnum.START_NODE.getType());
                    params.put("workflowIdIn", workflowIds);
                    List<WorkflowNodeEntity> workflowNodeEntityList = workflowNodeModel.findEntitys(params);

                    // redis设置并行数量缓存值
                    String key = workflowTransferPOJO.getCorpid() + StringConstant.UNDER_LINE + workflowTransferPOJO.getLinkKey() + StringConstant.UNDER_LINE + workflowTransferPOJO.getFromStageId();
                    paasRedisHelper.setValue(RedisPrefixConstant.WORKFLOW_CONCURRENT_NUM_LOCK, key, workflowNodeEntityList.size(), RedisTimeConstant.LONG_DURATION);

                    // 备份数据处理
                    PaasFormDataEntity paasFormDataEntity = proFormDataHelp.getFormData(corpid, pojoData.getSaasMark(), pojoData.getBusinessType(), pojoData.getId());

                    long now = DateTimeUtil.getInt();

                    FormDataUpdateService formDataUpdateService = businessUpdateMap.get(pojoData.getBusinessType());
                    JSONObject dataObject = formDataUpdateService.backupDataOtherInfo(paasFormDataEntity.getData(), corpid, pojoData.getId());

                    WorkflowBackupDataEntity workflowBackupDataEntity = new WorkflowBackupDataEntity(corpid, paasFormDataEntity.getAppId(), paasFormDataEntity.getFormId(), paasFormDataEntity.getMenuId(), 0L, 0L, paasFormDataEntity.getId(), dataObject, now, now, DelEnum.NORMAL.getDel());

                    Data oldData = new Data(paasFormDataEntity.getAppId(), paasFormDataEntity.getMenuId(), paasFormDataEntity.getFormId(), paasFormDataEntity.getId(), paasFormDataEntity.getData(), pojoData.getBusinessType(), pojoData.getSaasMark(), 0L, pojoData.getSubBusinessType());


                    for (WorkflowNodeEntity nodeEntity : workflowNodeEntityList) {
                        // 备份数据处理
                        workflowBackupDataEntity.setId(0L);
                        workflowBackupDataModel.insert(workflowBackupDataEntity);

                        Data data = new Data(nodeEntity.getAppId(), nodeEntity.getMenuId(), nodeEntity.getFormId(), pojoData.getId(), pojoData.getData(), nodeEntity.getBusinessType(), nodeEntity.getSaasMark(), nodeEntity.getId(), pojoData.getSubBusinessType());

                        WorkflowTransferPOJO transferPOJO = new WorkflowTransferPOJO();
                        transferPOJO.setData(data);
                        transferPOJO.setUser(workflowTransferPOJO.getUser());
                        transferPOJO.setCorpid(corpid);
                        transferPOJO.setFlowDatas(null);
                        transferPOJO.setOperate(workflowTransferPOJO.getOperate());
                        transferPOJO.setIsImport(workflowTransferPOJO.getIsImport());
                        transferPOJO.setIsFromStage(workflowTransferPOJO.getIsFromStage());
                        transferPOJO.setBackupDataId(workflowBackupDataEntity.getId());

                        oldData.setNodeId(nodeEntity.getId());
                        transferPOJO.setOldData(oldData);

                        transferPOJO.setParentExecutionId(workflowTransferPOJO.getExecutionId());
                        // 在消费者开始节点处理生成
//                            transferPOJO.setExecutionId();
                        transferPOJO.setFromStageId(workflowTransferPOJO.getFromStageId());
                        transferPOJO.setToStageId(workflowTransferPOJO.getToStageId());
                        transferPOJO.setLinkKey(workflowTransferPOJO.getLinkKey());
                        transferPOJO.setExecutionType(WorkflowExecutionTypeEnum.AFTER_STAGE.getCode());
                        transferPOJO.setStageProcessId(workflowTransferPOJO.getStageProcessId());


                        WorkflowRabbitmqDTO workflowRabbitmqDTO = new WorkflowRabbitmqDTO();
                        workflowRabbitmqDTO.setWorkflowTransferPOJO(transferPOJO);
                        workflowRabbitmqDTO.setWorkflowNodeEntity(nodeEntity);
                        workflowRabbitmqDTO.setSaasNeedRedundantAttrPojo(new SaasNeedRedundantAttrPojo());
                        workflowProducer.startWorkflow(workflowRabbitmqDTO);
                    }


                } else {
                    processBeforeStage(workflowTransferPOJO, corpid, pojoData);
                }

                // TODO: 2022/1/25 工作流触发工作流

            } else {
                // 工作流触发工作流
                // TODO: 2022/1/24

            }

        } else if (Objects.equals(workflowTransferPOJO.getExecutionType(), WorkflowExecutionTypeEnum.AFTER_STAGE.getCode())) {
            // 阶段跳出后，触发阶段进入前
            if (workflowTransferPOJO.getIsFromStage()) {

                if (!Objects.equals(workflowTransferPOJO.getParentExecutionId(), 0L)) {
                    // redis设置并行数量缓存值
                    String key = workflowTransferPOJO.getCorpid() + StringConstant.UNDER_LINE + workflowTransferPOJO.getLinkKey() + StringConstant.UNDER_LINE + workflowTransferPOJO.getFromStageId();
                    Long decrNum = paasRedisHelper.getDecrNum(RedisPrefixConstant.WORKFLOW_CONCURRENT_NUM_LOCK, key, 1);
                    if (decrNum <= 0) {
                        processBeforeStage(workflowTransferPOJO, corpid, pojoData);
                    }
                }

            }

        } else if (Objects.equals(workflowTransferPOJO.getExecutionType(), WorkflowExecutionTypeEnum.BEFORE_STAGE.getCode())) {
            // 阶段进入前，直接结束，后续不做其他操作

        } else if (Objects.equals(workflowTransferPOJO.getExecutionType(), WorkflowExecutionTypeEnum.WORKFLOW.getCode())) {
            // 工作流触发工作流，目前只触发一级的，所以后续也不做操作, 所以暂时不处理
        }
    }


    /**
     * Description: 阶段推进器阶段到达前处理
     * @param workflowTransferPOJO
	 * @param corpid
	 * @param pojoData
     * @return void
     * @throws
     * @author 魏荣杰
     * @date 2022/2/14 09:17
     * @since
     */
    private void processBeforeStage(WorkflowTransferPOJO workflowTransferPOJO, String corpid, Data pojoData) throws XbbException {
        Long toStageId = workflowTransferPOJO.getToStageId();
        Long fromStageId = workflowTransferPOJO.getFromStageId();
        if (Objects.isNull(fromStageId)) {
            return;
        }
        Map<String, Object> param = new HashMap<>();
        param.put(ParameterConstant.CORPID, corpid);
        param.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        param.put(ParameterConstant.FORMID, pojoData.getFormId());
        param.put("stageId", toStageId);
        param.put("relatedStageId", fromStageId);
        param.put("triggerType", StageWorkflowTriggerTypeEnum.BEFORE_STAGE.getCode());
        param.put("stageProcessId", workflowTransferPOJO.getStageProcessId());

        List<StageWorkflowEntity> stageWorkflowEntityList = stageWorkflowModel.findEntitys(param);

        if (CollectionsUtil.isNotEmpty(stageWorkflowEntityList)) {
            List<Long> workflowIds = stageWorkflowEntityList.stream().map(StageWorkflowEntity::getWorkflowId).collect(Collectors.toList());
            Map<String, Object> params = new HashMap<>();
            params.put(ParameterConstant.CORPID, corpid);
            params.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
            params.put(ParameterConstant.ID_IN, workflowIds);
            params.put(ParameterConstant.ENABLE, BasicConstant.ONE);
            List<WorkflowEntity> workflowEntities = workflowModel.findEntitys(params);

            workflowIds = workflowEntities.stream().map(WorkflowEntity::getId).collect(Collectors.toList());
            params.clear();
            params.put(ParameterConstant.CORPID, corpid);
            params.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
            params.put("type", WorkflowNodeTypeEnum.START_NODE.getType());
            params.put("workflowIdIn", workflowIds);
            List<WorkflowNodeEntity> workflowNodeEntityList = workflowNodeModel.findEntitys(params);


            // redis设置并行数量缓存值
//            String key = workflowTransferPOJO.getCorpid() + StringConstant.UNDER_LINE + workflowTransferPOJO.getLinkKey() + StringConstant.UNDER_LINE + workflowTransferPOJO.getToStageId();
//            paasRedisHelper.setValue(RedisPrefixConstant.WORKFLOW_CONCURRENT_NUM_LOCK, key, workflowNodeEntityList.size(), RedisTimeConstant.LONG_DURATION);

            // 备份数据处理
            PaasFormDataEntity paasFormDataEntity = proFormDataHelp.getFormData(corpid, pojoData.getSaasMark(), pojoData.getBusinessType(), pojoData.getId());

            FormDataUpdateService formDataUpdateService = businessUpdateMap.get(pojoData.getBusinessType());
            JSONObject dataObject = formDataUpdateService.backupDataOtherInfo(paasFormDataEntity.getData(), corpid, pojoData.getId());

            long now = DateTimeUtil.getInt();
            WorkflowBackupDataEntity workflowBackupDataEntity = new WorkflowBackupDataEntity(corpid, paasFormDataEntity.getAppId(), paasFormDataEntity.getFormId(), paasFormDataEntity.getMenuId(), 0L, 0L, paasFormDataEntity.getId(), dataObject, now, now, DelEnum.NORMAL.getDel());

            Data oldData = new Data(paasFormDataEntity.getAppId(), paasFormDataEntity.getMenuId(), paasFormDataEntity.getFormId(), paasFormDataEntity.getId(), paasFormDataEntity.getData(), pojoData.getBusinessType(), pojoData.getSaasMark(), 0L, pojoData.getSubBusinessType());


            for (WorkflowNodeEntity nodeEntity : workflowNodeEntityList) {

                // 备份数据处理
                workflowBackupDataEntity.setId(0L);
                workflowBackupDataModel.insert(workflowBackupDataEntity);

                Data data = new Data(nodeEntity.getAppId(), nodeEntity.getMenuId(), nodeEntity.getFormId(), pojoData.getId(), pojoData.getData(), nodeEntity.getBusinessType(), nodeEntity.getSaasMark(), nodeEntity.getId(), pojoData.getSubBusinessType());

                WorkflowTransferPOJO transferPOJO = new WorkflowTransferPOJO();
                transferPOJO.setData(data);
                transferPOJO.setUser(workflowTransferPOJO.getUser());
                transferPOJO.setCorpid(corpid);
                transferPOJO.setFlowDatas(null);
                transferPOJO.setOperate(workflowTransferPOJO.getOperate());
                transferPOJO.setIsImport(workflowTransferPOJO.getIsImport());
                transferPOJO.setIsFromStage(workflowTransferPOJO.getIsFromStage());
                transferPOJO.setParentExecutionId(workflowTransferPOJO.getExecutionId());

                transferPOJO.setBackupDataId(workflowBackupDataEntity.getId());

                oldData.setNodeId(nodeEntity.getId());
                transferPOJO.setOldData(oldData);

                // 在消费者开始节点处理生成
//                            transferPOJO.setExecutionId();
                transferPOJO.setFromStageId(fromStageId);
                transferPOJO.setToStageId(workflowTransferPOJO.getToStageId());
                transferPOJO.setLinkKey(workflowTransferPOJO.getLinkKey());
                transferPOJO.setExecutionType(WorkflowExecutionTypeEnum.BEFORE_STAGE.getCode());
                transferPOJO.setStageProcessId(workflowTransferPOJO.getStageProcessId());

                WorkflowRabbitmqDTO workflowRabbitmqDTO = new WorkflowRabbitmqDTO();
                workflowRabbitmqDTO.setWorkflowTransferPOJO(transferPOJO);
                workflowRabbitmqDTO.setWorkflowNodeEntity(nodeEntity);
                workflowRabbitmqDTO.setSaasNeedRedundantAttrPojo(new SaasNeedRedundantAttrPojo());
                workflowProducer.startWorkflow(workflowRabbitmqDTO);
            }
        }
    }

    /**
     * 设置工作流操作的ThreadLocal，回调使用 businessType_operateCode
     * @param businessType
     * @param operateCode
     * 创建时间 2021/11/29 5:00 PM
     * 修改时间 2021/11/29 5:00 PM
     * @author chy
     */
    private void setWorkFlowOperateValue(Integer businessType, Integer operateCode) {
        String workFlowOperateValue = null;
        if (Objects.equals(businessType, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode())) {
            workFlowOperateValue = XbbRefTypeEnum.CUSTOMER.getCode() + "_" + operateCode.toString();
        } else {
            workFlowOperateValue = businessType + "_" + operateCode.toString();
        }
        LOGGER.info("workFlowOperateValue:" + workFlowOperateValue);
        TransmittableThreadLocalUtil.setWorkFlowOperateValue(workFlowOperateValue);
    }

    /**
     * 如果是编辑进审批的话，将对进审批之前的数据进行备份，主要是为了后面在拒绝审批时，对数据进行还原，还原范围包括（主表数据，子表单数据，关联产品数据，团队数据等）
     * @param workflowTransferPOJO
     * @param workflowNodeEntity
     * @return 数据备份表id，在后续审批中将taskId置成当前任务的id
     * @throws XbbException
     */
    private Long backup(WorkflowTransferPOJO workflowTransferPOJO, WorkflowNodeEntity workflowNodeEntity, SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo) throws XbbException {
        if (!Objects.equals(workflowTransferPOJO.getOperate(), WorkflowOperateEnum.UPDATE.getType())) {
            return null;
        }
        String corpid = workflowTransferPOJO.getCorpid();
        WorkflowEntity workflowEntity = workflowModel.getByKey(workflowNodeEntity.getWorkflowId(), corpid);
        if (Objects.isNull(workflowEntity)) {
            throw new WorkflowException(ProErrorCodeEnum.API_ERROR_260037.getMsg());
        }
        Long backupDataId = workflowTransferPOJO.getBackupDataId();
        if (Objects.nonNull(backupDataId)) {
            WorkflowBackupDataEntity update = new WorkflowBackupDataEntity();
            update.setId(backupDataId);
            update.setCorpid(workflowTransferPOJO.getCorpid());
            update.setUpdateTime(DateTimeUtil.getInt());
            update.setWorkflowId(workflowNodeEntity.getWorkflowId());
            update.setTaskId(workflowTransferPOJO.getTaskId());
            workflowBackupDataModel.update(update);
            //更新工作流富文本备份数据
            WorkflowBackupRichTextEntity workflowBackupRichTextEntity = new WorkflowBackupRichTextEntity();
            workflowBackupRichTextEntity.setCorpid(workflowTransferPOJO.getCorpid());
            workflowBackupRichTextEntity.setBackupId(backupDataId);
            workflowBackupRichTextEntity.setUpdateTime(DateTimeUtil.getInt());
            workflowBackupRichTextEntity.setWorkflowId(workflowNodeEntity.getWorkflowId());
            workflowBackupRichTextEntity.setTaskId(workflowTransferPOJO.getTaskId());
            workflowBackupRichTextModel.updateByBackupId(workflowBackupRichTextEntity);
        }
        return backupDataId;
    }

    /**
     * 触发酷应用
     *
     * @param workflowRabbitmqDTO
     * @param updateFlag
     */
    private void coolAppCard(WorkflowRabbitmqDTO workflowRabbitmqDTO, boolean updateFlag, Integer flowStatus, Integer taskType) {
        Runnable runnable = () -> {
            if (Objects.isNull(workflowRabbitmqDTO.getOperatorId())) {
                return;
            }

            WorkflowTransferPOJO workflowTransferPOJO = workflowRabbitmqDTO.getWorkflowTransferPOJO();
            String corpid = workflowTransferPOJO.getCorpid();
            Integer saasMark = workflowTransferPOJO.getData().getSaasMark();
            Integer businessType = workflowTransferPOJO.getData().getBusinessType();
            UserVO userVO;
            try {
                userVO = userModel.getUserVO(corpid, workflowRabbitmqDTO.getOperatorId(), true, true);
            } catch (Exception e) {
                LOGGER.error("获取操作人失败", e);
                userVO = null;
            }
            if (Objects.isNull(userVO)) {
                return;
            }
            WorkflowNodeEntity workflowNodeEntity = workflowRabbitmqDTO.getWorkflowNodeEntity();

            CoolAppWorkflowCardDTO coolAppWorkflowCardDTO = new CoolAppWorkflowCardDTO(corpid, userVO, PlatFormEnum.INTERNAL.getValue(), workflowRabbitmqDTO.getOpenConversationId(),
                    workflowNodeEntity.getAppId(), workflowNodeEntity.getMenuId(), workflowNodeEntity.getFormId(), saasMark, businessType, workflowTransferPOJO.getTaskId(),
                    workflowNodeEntity.getWorkflowId(), workflowTransferPOJO.getData().getId(), flowStatus, taskType);
            if (updateFlag) {
                try {
                    if (TaskTypeEnum.AGAIN_COMMIT.getType().equals(taskType)) {
                        coolAppWorkflowCardDTO.setPreTaskId(workflowRabbitmqDTO.getPreTaskId());
                    }
                    coolAppWorkflowCardDTO.setOpenConversationId(null);
                    coolAppCardService.updateWorkflowCard(coolAppWorkflowCardDTO);
                } catch (Exception e) {
                    LOGGER.error("更新酷应用卡片失败", e);
                }
            } else {
                try {
                    coolAppCardService.sendWorkflowCard(coolAppWorkflowCardDTO);
                } catch (Exception e) {
                    LOGGER.error("发送酷应用卡片失败", e);
                }
            }
        };
        threadPoolBeanConfig.interactiveCardThreadPool().execute(runnable);
    }
}
